home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / archivers / xfd / developer / sources / asm / crunch.a < prev    next >
Text File  |  1999-06-14  |  12KB  |  584 lines

  1. * Programmheader
  2. *
  3. *    Name:        Crunch
  4. *    Author:        SDI
  5. *    Distribution:    PD
  6. *    Description:    XFD external decruncher for recognising Crunch1.x
  7. *    Compileropts:    -
  8. *    Linkeropts:    -
  9. *
  10. * 1.0   22.11.98 : first version
  11. * 1.1   09.12.98 : added normal reloc version
  12. * 1.2   11.12.98 : added SEG version
  13. * 1.3   29.12.98 : added BSS hunk support
  14. * 1.4   19.01.99 : added Data scan
  15. * 1.5   09.03.99 : enforcer hit fixed
  16.  
  17.         INCLUDE    "AINCLUDE:IncDirs.i"
  18.         INCLUDE    "lvo.i"
  19.  
  20.         INCLUDE    "libraries/xfdmaster.i"
  21.         INCLUDE    "exec/memory.i"
  22.         INCLUDE "dos/doshunks.i"
  23.  
  24.         * head function for tests
  25. *        INCLUDE    "xfdExeHead.a"
  26.  
  27. ForeMan        MOVEQ    #-1,D0        ;security
  28.         RTS
  29.  
  30.         DC.L    XFDF_ID
  31.         DC.W    1,0
  32.         DC.L    0,0,S_Crunch
  33.  
  34.         DC.B    "$VER: Crunch 1.5 (09.03.1999) by SDI",0
  35. N_Crunch    DC.B    "Crunch 1.3",0
  36. N_CrunchSeg    DC.B    "Crunch 1.3 Seg",0
  37. N_CrunchData    DC.B    "Crunch 1.3 Data",0
  38.         EVEN
  39.  
  40. S_Crunch    DC.L    S_CrunchSeg    ;next slave
  41.         DC.W    2        ;version
  42.         DC.W    36        ;master version
  43.         DC.L    N_Crunch    ;name
  44.         DC.W    XFDPFF_RELOC
  45.         DC.W    0
  46.         DC.L    RB_Crunch    ;recog buffer
  47.         DC.L    DB_Crunch    ;decrunch buffer
  48.         DC.L    0        ;recog segment
  49.         DC.L    0        ;decrunch segment
  50.         DC.W    0,0
  51.         DC.L    140        ;MinBufSize
  52.  
  53. S_CrunchSeg    DC.L    S_CrunchData    ;next slave
  54.         DC.W    2        ;version
  55.         DC.W    36        ;master version
  56.         DC.L    N_CrunchSeg    ;name
  57.         DC.W    XFDPFF_RELOC
  58.         DC.W    0
  59.         DC.L    RB_CrunchSeg    ;recog buffer
  60.         DC.L    DB_CrunchSeg    ;decrunch buffer
  61.         DC.L    0        ;recog segment
  62.         DC.L    0        ;decrunch segment
  63.         DC.W    0,0
  64.         DC.L    140        ;MinBufSize
  65.  
  66. S_CrunchData    DC.L    0        ;next slaves
  67.         DC.W    2        ;version
  68.         DC.W    38        ;master version
  69.         DC.L    N_CrunchData    ;name
  70.         DC.W    XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
  71.         DC.W    0
  72.         DC.L    RB_CrunchData    ;recog buffer
  73.         DC.L    DB_CrunchData    ;decrunch buffer
  74.         DC.L    SD_CrunchData    ;recog segment
  75.         DC.L    VD_CrunchData    ;decrunch segment
  76.         DC.W    0,0
  77.         DC.L    12        ;MinBufSize
  78.  
  79. RB_Crunch    MOVEQ    #0,D0
  80.         CMP.L    #$000003F3,(A0)
  81.         BNE.B    .Exit
  82.         TST.L    4(A0)
  83.         BNE.B    .Exit
  84.         MOVE.L    8(A0),D1
  85.         LSL.L    #2,D1
  86.         ADD.L    D1,A0
  87.         CMP.L    #$48E7FFFF,7*4(A0)
  88.         BNE.B    .Exit
  89.         CMP.L    #$70004E96,10*4(A0)
  90.         BNE.B    .Exit
  91.         CMP.L    #$584C4E75,20*4(A0)
  92.         BNE.B    .Exit
  93.         CMP.L    #$000003EB,21*4(A0)
  94.         BNE.B    .Exit
  95.         MOVEQ    #1,D0
  96. .Exit        RTS
  97.  
  98. RB_CrunchSeg    MOVEQ    #0,D0
  99.         CMP.L    #$000003F3,(A0)
  100.         BNE.B    .Exit
  101.         TST.L    4(A0)
  102.         BNE.B    .Exit
  103.         MOVE.L    8(A0),D1
  104.         LSL.L    #2,D1
  105.         ADD.L    D1,A0
  106.         CMP.L    #$48E7FFFF,7*4(A0)
  107.         BNE.B    .Exit
  108.         CMP.L    #$70006146,10*4(A0)
  109.         BNE.B    .Exit
  110.         CMP.L    #$202800AC,20*4(A0)
  111.         BNE.B    .Exit
  112.         CMP.L    #$6712E588,21*4(A0)
  113.         BNE.B    .Exit
  114.         MOVEQ    #1,D0
  115. .Exit        RTS
  116.  
  117. RB_CrunchData    MOVEQ    #0,D0
  118.         CMPI.L    #$43525561,(A0)
  119.         BNE.B    .Exit
  120.         MOVE.L    4(A0),xfdrr_FinalTargetLen(A1)
  121.         MOVE.L    4(A0),xfdrr_MinTargetLen(A1)
  122.         MOVEQ    #1,D0
  123. .Exit        RTS
  124.  
  125. SD_CrunchData    MOVEQ    #0,D0
  126.         CMPI.L    #$43525561,(A0)
  127.         BNE.B    .Exit
  128.         MOVEQ    #1,D0
  129. .Exit        RTS
  130.  
  131. VD_CrunchData    MOVEQ    #12,D1
  132.         ADD.L    8(a0),D1    ;crlen
  133.         CMP.L    D0,D1        ;crlen > buflen ??
  134.         BGT.B    .Exit
  135.         MOVE.L    4(A0),D0
  136.         SUB.L    8(A0),D0    ;cr > uncr ??
  137.         BMI.B    .Exit
  138.         MOVE.L    D1,D0
  139.         RTS
  140. .Exit        MOVEQ    #0,D0
  141.         RTS
  142.  
  143. DB_CrunchSeg    MOVEM.L    D7/A4-A6,-(A7)
  144.         MOVE.L    A0,A5
  145.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  146.         MOVE.L    xfdm_ExecBase(A6),A6
  147.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  148.  
  149.         MOVE.L    8(A4),D7
  150.         SUBQ.L    #1,D7        * destination hunk numbers
  151.  
  152.         MOVE.L    A4,A0
  153.         BSR.B    GetCruSegSize
  154.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  155.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  156.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  157.         JSR    _LVOAllocMem(A6)
  158.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  159.         BEQ.B    .NoMem
  160.  
  161.         MOVE.L    D0,A1
  162.         MOVE.L    A4,A0
  163.         BSR.W    DecrunchCruSeg
  164.  
  165.         CLR.W    xfdbi_Error(A5)
  166.         MOVEQ    #1,D0
  167. .NoMem        MOVEM.L    (A7)+,D7/A4-A6
  168.         RTS
  169.  
  170.         * A0 is buffer
  171.         * D7 is num of hunks
  172. GetCruSegSize    MOVE.L    D6,-(A7)
  173.         MOVE.L    D7,D1
  174.         LSL.L    #2,D1
  175.         MOVE.L    D1,D0
  176.         ADD.L    #$1D0,D1
  177.         LEA    (A0,D1.L),A0    * get first hunk pointer
  178.         ADD.L    #20,D0        * header size
  179.         MOVEQ    #0,D6
  180. .MainLoop    ADD.L    #12,D0        * hunk, size, HUNK_END
  181.         CMP.W    #HUNK_BSS,2(A0)
  182.         BEQ.B    .BSS
  183.         CMP.L    #'CRUa',8(A0)
  184.         BEQ.B    .crunched
  185.         MOVE.L    4(A0),D1
  186.         LSL.L    #2,D1
  187.         ADD.L    D1,D0
  188.         LEA    8(A0,D1.L),A0
  189.         BRA.B    .loopend
  190. .BSS        ADDQ.L    #8,A0
  191.         BRA.B    .loopend
  192. .crunched    ADD.L    12(A0),D0
  193.         MOVE.L    16(A0),D1
  194.         ADDQ.L    #3,D1
  195.         AND.L    #-4,D1
  196.         LEA    20(A0,D1.L),A0
  197. .loopend    BSR.B    .ParseReloc
  198.         ADDQ.L    #1,D6
  199.         CMP.B    D6,D7
  200.         BNE.B    .MainLoop
  201.         MOVE.L    (A7)+,D6
  202.         RTS
  203.  
  204. .ParseReloc    CMP.L    #HUNK_RELOC32,(A0)
  205.         BNE.B    .end
  206.         ADDQ.L    #4,A0
  207.         ADDQ.L    #4,D0        * HUNK_RELOC
  208. .PRLoop        ADDQ.L    #4,D0
  209.         MOVE.L    (A0)+,D1
  210.         BEQ.B    .end
  211.         LSL.L    #2,D1
  212.         ADDQ.L    #4,D1        * related hunk
  213.         LEA    (A0,D1.L),A0
  214.         ADD.L    D1,D0
  215.         BRA.B    .PRLoop
  216. .end        RTS
  217.  
  218.         * A0 is buffer
  219.         * A1 is destination
  220.         * A4 is source buffer
  221.         * D7 is num of hunks
  222. DecrunchCruSeg    MOVEM.L    D2-D6/A2,-(A7)    * hunk size == def size - 512
  223.         MOVE.L    D7,D0        * - reloc space
  224.         LSL.L    #2,D0
  225.         ADD.L    #$1D0,D0
  226.         LEA    (A0,D0.L),A0    * get first hunk pointer
  227.         MOVEQ    #0,D6
  228.         MOVE.L    #HUNK_HEADER,(A1)+
  229.         CLR.L    (A1)+
  230.         MOVE.L    D7,(A1)+    * numhunks
  231.         CLR.L    (A1)+        * starthunk
  232.         MOVE.L    D7,D0
  233.         SUBQ.L    #1,D0
  234.         MOVE.L    D0,(A1)+    * endhunk
  235.         MOVE.L    A1,A2        * start of hunk sizes
  236.         MOVE.L    D7,D0
  237.         LSL.L    #2,D0
  238.         LEA    (A1,D0.L),A1    * skip space
  239. .MainLoop    MOVE.L    (A0)+,(A1)+    * hunk type
  240.         MOVE.L    D6,D0
  241.         LSL.L    #2,D0
  242.         MOVE.L    24(A4,D0.L),D5
  243.         MOVE.L    D5,D4
  244.         AND.L    #$E0000000,D4    * only bits
  245.         AND.L    #$1FFFFFFF,D5    * strip bits
  246.         MOVEQ    #1,D3        * uncrunched
  247.         CMP.W    #HUNK_BSS,-2(A0)
  248.         BEQ.B    .BSS
  249.         CMP.L    #'CRUa',4(A0)
  250.         BEQ.B    .crunched
  251.         MOVE.L    (A0)+,D0
  252.         MOVE.L    D0,(A1)+
  253. .copyhunk    TST.L    D0
  254.         BEQ.B    .loopend
  255.         MOVE.L    (A0)+,(A1)+
  256.         SUBQ.L    #1,D0
  257.         BRA.B    .copyhunk
  258. .BSS        MOVE.L    (A0)+,(A1)+
  259.         BRA.B    .loopend
  260. .crunched    MOVEQ    #0,D3        * crunched
  261.         ADDQ.L    #4,A0
  262.         MOVE.L    4(A0),D0
  263.         LSR.L    #2,D0
  264.         MOVE.L    D0,(A1)+    * store size
  265.         MOVEM.L    A0-A1,-(A7)
  266.         BSR.W    DecrunchCru
  267.         MOVEM.L    (A7)+,A0-A1
  268.         ADD.L    4(A0),A1
  269.         MOVE.L    8(A0),D1
  270.         ADDQ.L    #3,D1
  271.         AND.L    #-4,D1
  272.         LEA    12(A0,D1.L),A0
  273.         SUB.L    #128,D5
  274. .loopend    BSR.B    .CopyReloc
  275.         OR.L    D4,D5        * copy bits
  276.         MOVE.L    D5,(A2)+    * store size
  277.         MOVE.L    #HUNK_END,(A1)+
  278.         ADDQ.L    #1,D6
  279.         CMP.B    D6,D7
  280.         BNE.W    .MainLoop
  281.         MOVEM.L    (A7)+,D2-D6/A2
  282.         RTS
  283.  
  284. .CopyReloc    MOVE.L    A1,D0        * store pointer
  285.         CMP.L    #HUNK_RELOC32,(A0)
  286.         BNE.B    .end
  287.         MOVE.L    (A0)+,(A1)+
  288. .CRLoop        MOVE.L    (A0)+,D1
  289.         MOVE.L    D1,(A1)+
  290.         BEQ.B    .end
  291.         MOVE.L    (A0)+,D2
  292.         SUB.L    D3,D2        * subtract 1, when uncrunched
  293.         MOVE.L    D2,(A1)+    * copy hunkID
  294. .RCLoop        MOVE.L    (A0)+,(A1)+    * copy reloc
  295.         SUBQ.L    #1,D1
  296.         BNE.B    .RCLoop
  297.         BRA.B    .CRLoop
  298. .end        TST.L    D3
  299.         BNE.B    .endR
  300.         MOVE.L    A1,D1    * subtract
  301.         SUB.L    D0,D1    * reloc space
  302.         LSR.L    #2,D1    * from filesize
  303.         SUB.L    D1,D5
  304. .endR        RTS
  305.  
  306. DB_Crunch    MOVEM.L    D5-D7/A2-A6,-(A7)
  307.         MOVE.L    A0,A5
  308.         MOVEQ    #0,D6                * return value
  309.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  310.         MOVE.L    xfdm_ExecBase(A6),A6
  311.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  312.  
  313.         MOVE.L    8(A4),D7
  314.         SUBQ.L    #3,D7        * destination hunk numbers
  315.  
  316.         MOVE.L    D7,D1
  317.         LSL.L    #2,D1
  318.         MOVE.L    D1,D0
  319.         LSL.L    #1,D0
  320.         ADD.L    D1,D0    * multiply with 12
  321.         ADD.L    #$1E4,D0
  322.  
  323.         LEA.L    (A4,D0.L),A2
  324.         MOVE.L    4(A2),D5
  325.         MOVE.L    D5,D0
  326.         MOVEQ    #0,D1
  327.         JSR    _LVOAllocMem(A6)
  328.         TST.L    D0
  329.         BEQ.B    .NoMem
  330.         MOVE.L    D0,A3
  331.         
  332.         MOVE.L    D0,A1
  333.         MOVE.L    A2,A0
  334.         BSR.W    DecrunchCru
  335.  
  336.         MOVE.L    A3,A0
  337.         BSR.W    CountCruSize
  338.  
  339.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  340.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  341.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  342.         JSR    _LVOAllocMem(A6)
  343.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  344.         BEQ.B    .NoMem2
  345.  
  346.         MOVEA.L    A3,A0
  347.         MOVEA.L    D0,A1
  348.         BSR.W    MakeCruFile
  349.  
  350.         CLR.W    xfdbi_Error(A5)
  351.         MOVEQ    #1,D6                * set true
  352. .NoMem2        MOVE.L    D5,D0
  353.         MOVE.L    A3,A1
  354.         JSR    _LVOFreeMem(A6)
  355. .NoMem        MOVE.L    D6,D0
  356.         MOVEM.L    (A7)+,D5-D7/A2-A6
  357.         RTS
  358.  
  359. DB_CrunchData    MOVEM.L    A4-A6,-(A7)
  360.         MOVE.L    A0,A5
  361.         MOVE.L    xfdm_ExecBase(A6),A6
  362.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  363.  
  364.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  365.         MOVE.L    4(A4),D0
  366.         MOVE.L    xfdbi_UserTargetBuf(A5),A1
  367.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  368.  
  369.         BTST.B    #XFDFB_USERTARGET,1+xfdbi_Flags(A5)
  370.         BNE.B    .Decrunch
  371.  
  372.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  373.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  374.         JSR    _LVOAllocMem(A6)
  375.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  376.         BEQ.B    .End
  377.         MOVE.L    D0,A1
  378. .Decrunch    MOVEA.L    A4,A0
  379.         BSR.B    DecrunchCru
  380.         CLR.W    xfdbi_Error(A5)
  381.         MOVEQ    #1,D0
  382. .End        MOVEM.L    (A7)+,A4-A6
  383.         RTS
  384.  
  385. DecrunchCru    MOVEM.L    D2-D6/A2-A4,-(A7)
  386.         MOVEA.L    A1,A2
  387.         ADDA.L    4(A0),A1
  388.         ADDQ.W    #8,A0
  389.         ADDA.L    (A0)+,A0
  390.         LEA    Sub1(PC),A3
  391.         MOVEQ    #8,D5
  392.         MOVE.W    #$00FF,D6
  393.         MOVE.B    -(A0),D4
  394. .Dec1        CMPA.L    A1,A2
  395.         BCS.B    .Dec2
  396.         MOVEM.L    (A7)+,D2-D6/A2-A4
  397.         RTS
  398.  
  399. .Dec2        JSR    (A3)
  400.         BCS.B    .Dec3
  401.         MOVE.B    -(A0),-(A1)
  402.         BRA.B    .Dec1
  403. .Dec3        MOVEQ    #0,D0
  404.         MOVEQ    #0,D1
  405.         MOVEQ    #0,D2
  406.         JSR    (A3)
  407.         BCC.B    .Dec4
  408.         MOVEQ    #0,D1
  409.         MOVEQ    #2,D2
  410.         JSR    (A3)
  411.         BCC.B    .Dec4
  412.         MOVEQ    #1,D1
  413.         MOVEQ    #4,D2
  414.         JSR    (A3)
  415.         BCC.B    .Dec4
  416.         MOVEQ    #1,D1
  417.         MOVEQ    #8,D2
  418.         JSR    (A3)
  419.         BCC.B    .Dec4
  420.         MOVEQ    #2,D1
  421.         MOVEQ    #$000C,D2
  422.         JSR    (A3)
  423.         BCC.B    .Dec4
  424.         MOVEQ    #$0014,D2
  425.         MOVE.B    -(A0),D0
  426.         CMP.B    D6,D0
  427.         BNE.B    .Dec5
  428.         ADD.W    D0,D2
  429.         MOVE.B    -(A0),D0
  430.         ROR.W    #8,D0
  431.         MOVE.B    -(A0),D0
  432.         BRA.B    .Dec5
  433. .Dec4        JSR    (A3)
  434.         ADDX.B    D0,D0
  435.         DBRA    D1,.Dec4
  436. .Dec5        ADD.W    D0,D2
  437.         BNE.B    .Dec6
  438.         MOVEQ    #$0010,D1
  439.         JSR    (A3)
  440.         BCC.B    .Dec7
  441.         MOVEQ    #$0014,D1
  442.         JSR    (A3)
  443.         BCC.B    .Dec7
  444.         MOVEQ    #$0018,D1
  445.         JSR    (A3)
  446.         BCC.B    .Dec7
  447.         MOVEQ    #$001C,D1
  448.         BRA.B    .Dec7
  449. .Dec6        MOVEQ    #0,D1
  450.         JSR    (A3)
  451.         ADDX.B    D1,D1
  452.         JSR    (A3)
  453.         ADDX.B    D1,D1
  454.         LSL.B    #2,D1
  455. .Dec7        MOVEM.W    $A(A3,D1.W),D0/A4    * access data field, A3 points
  456.         MOVEQ    #0,D3            * to Sub1, which is $A bytes
  457.         CMP.W    D5,D0
  458.         BCS.B    .Dec8
  459.         MOVE.B    -(A0),D3
  460.         SUBQ.W    #8,D0
  461. .Dec8        JSR    (A3)
  462.         ADDX.W    D3,D3
  463.         DBRA    D0,.Dec8
  464.         ADDA.L    D3,A4
  465.         ADDA.L    A1,A4
  466.         MOVE.B    (A4),-(A1)
  467. .Dec9        MOVE.B    -(A4),-(A1)
  468.         DBRA    D2,.Dec9
  469.         BRA.W    .Dec1
  470.  
  471. Sub1        ADD.B    D4,D4
  472.         BNE.B    .SubEnd
  473.         MOVE.B    -(A0),D4
  474.         ADDX.B    D4,D4
  475. .SubEnd        RTS
  476.         DC.W    06,$0000,09,$0080,12,$0480,13,$2480,05,$0000
  477.         DC.W    06,$0040,06,$00C0,06,$0140
  478.  
  479.  
  480.         * A0 is buffer
  481.         * D7 is num of hunks
  482. CountCruSize    MOVEM.L    D2/D6,-(A7)
  483.         MOVE.L    D7,D0
  484.         LSL.L    #4,D0        * size, HUNK_CODE, size, HUNK_END --> 4*4 bytes
  485.         ADD.L    #20,D0        * header hunk
  486.         MOVEQ    #0,D6        * hunk counter
  487. .MainLoop    MOVE.L    (A0)+,D1
  488.         MOVE.L    D1,D2
  489.         ANDI.L    #-4,D1        * last bits are CHIP/RELOC markers
  490.         ADD.L    D1,D0        * add that size
  491.         LEA    (A0,D1.L),A0    * skip that part
  492.         BTST    #1,D2        * no reloc hunks
  493.         BEQ.B    .LoopEnd
  494.         ADDQ.L    #4,D0        * place for HUNK_RELOC32
  495. .Reloc        MOVE.W    (A0)+,D1
  496.         ADDQ.L    #4,D0    * add size or empty place for last marker
  497.         TST.W    D1
  498.         BEQ.B    .LoopEnd
  499.         ADDQ.L    #8,D0        * add related hunk and first reloc
  500.         ADDQ.L    #6,A0
  501.         SUBQ.W    #2,D1
  502.         BMI.B    .Reloc
  503. .RelLoop    ADDQ.L    #4,D0
  504.         MOVE.W    (A0)+,D2    * normally we have word offsets
  505.         BNE.B    .Skip
  506.         MOVE.L    (A0)+,D2    * skip LONG offset
  507. .Skip        DBRA.B    D1,.RelLoop
  508.         BRA.B    .Reloc
  509. .LoopEnd    ADDQ.L    #1,D6        * next hunk
  510.         CMP.L    D6,D7
  511.         BNE.B    .MainLoop
  512.         MOVEM.L    (A7)+,D2/D6
  513.         RTS
  514.  
  515.         * A0 is buffer
  516.         * A1 is destination
  517.         * A4 is source file (crunched)
  518.         * D7 is num of hunks
  519. MakeCruFile    MOVEM.L    D2/D6/A4,-(A7)
  520.         MOVE.L    #HUNK_HEADER,(A1)+
  521.         CLR.L    (A1)+
  522.         MOVE.L    D7,(A1)+    * numhunks
  523.         CLR.L    (A1)+        * starthunk
  524.         MOVE.L    D7,D0
  525.         SUBQ.L    #1,D0
  526.         MOVE.L    D0,(A1)+    * endhunk
  527.         LEA    24(A4),A4    * start of sizes
  528. .HeadLoop    MOVE.L    (A4)+,(A1)+    * copy sizes
  529.         DBRA    D0,.HeadLoop
  530.  
  531.         MOVEQ    #0,D6
  532. .MainLoop    MOVE.L    (A0)+,D1
  533.         MOVE.L    D1,D2
  534.         LSR.L    #2,D1
  535.         BEQ.B    .BSS
  536.         MOVE.L    #HUNK_CODE,D0
  537.         BTST    #0,D2
  538.         BEQ.B    .Next
  539.         MOVE.L    #HUNK_DATA,D0
  540. .Next        MOVE.L    D0,(A1)+
  541.         MOVE.L    D1,(A1)+
  542.         BEQ.B    .DoRel
  543.         BRA.B    .CopyHunk
  544. .BSS        MOVE.L    #HUNK_BSS,(A1)+
  545.         MOVE.L    D6,D0
  546.         SUB.L    D7,D0
  547.         LSL.L    #2,D0
  548.         MOVE.L    (A4,D0.L),(A1)+
  549.         BRA.B    .DoRel
  550. .CopyHunk    MOVE.L    (A0)+,(A1)+
  551.         SUBQ.L    #1,D1
  552.         BNE.B    .CopyHunk
  553. .DoRel        BTST    #1,D2
  554.         BEQ.B    .LoopEnd
  555.         MOVE.L    #HUNK_RELOC32,(A1)+
  556. .Reloc        MOVEQ    #0,D1
  557.         MOVE.W    (A0)+,D1    * copy size
  558.         MOVE.L    D1,(A1)+
  559.         BEQ.B    .LoopEnd
  560.         MOVEQ    #0,D0
  561.         MOVE.W    (A0)+,D0
  562.         MOVE.L    D0,(A1)+    * move hunknum
  563.         MOVEQ    #0,D3
  564.         MOVE.L    (A0)+,D3
  565.         MOVE.L    D3,(A1)+
  566.         SUBQ.W    #2,D1
  567.         BMI.B    .Reloc
  568. .RelLoop    MOVEQ    #0,D0
  569.         MOVE.W    (A0)+,D0
  570.         BNE.B    .Skip
  571.         MOVE.L    (A0)+,D0
  572. .Skip        ADD.L    D0,D3
  573.         MOVE.L    D3,(A1)+
  574.         DBRA    D1,.RelLoop
  575.         BRA.B    .Reloc
  576.  
  577. .LoopEnd    MOVE.L    #HUNK_END,(A1)+
  578.         ADDQ.W    #1,D6
  579.         CMP.W    D6,D7
  580.         BNE.B    .MainLoop
  581.         MOVEM.L    (A7)+,D2/D6/A4
  582.         RTS
  583.         END
  584.